package trocabi.printer;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.List;

import org.krysalis.barcode4j.tools.UnitConv;

public class PrintBarcodes implements Pageable {

    private double x0, xm;
    private double y0, ym;
    private double sizeX, sizeY;
    private int barcode_par_page = 0;
    private double marge = 0;	//marge entre deux impressions. pourra être implémenté par la suite.
    private double dpi;
    private PageFormat format = null;
    private double downscale;
    private List<Barcode> liste = null;
    private int nbpage;
    private int nb_derniere_page;

    public PrintBarcodes(List<Barcode> liste, PageFormat format) {
        this.liste = liste;
        this.format = format;
        
        System.out.println("PageFormat:"+format.toString());
        //Note : PageFormat absolument nécéssaire!
        x0 = format.getImageableX();
        y0 = format.getImageableY();
        xm = x0 + format.getImageableWidth();
        ym = y0 + format.getImageableHeight();
        sizeX = format.getImageableWidth();
        sizeY = format.getImageableHeight();
        
        System.out.println(String.format("x0=%f y0=%f xm=%f, ym=%f sizeX=%f sizeY=%f",
                x0,y0,xm,ym,sizeX,sizeY));
        
        //Calcul du DPI (de façon à avoir 4cm pour la largeur, nos étiquettes étant largement plus longues)
        dpi = Barcode.getSizeX() / UnitConv.mm2in(40);
        downscale = (double) 72.0 / dpi;

        //Calcul du nouveau
        barcode_par_page = (int) Math.floor(sizeY / (Barcode.getSizeY() * downscale));
        nbpage = liste.size() / barcode_par_page;
        nb_derniere_page = liste.size() % barcode_par_page;
    }

    @Override
    public int getNumberOfPages() {
        if (liste == null) {
            return 0;
        }
        return (int) Math.ceil((double) liste.size() / (double) barcode_par_page);
    }

    @Override
    public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
        return format;
    }

    @Override
    public Printable getPrintable(final int id_page) throws IndexOutOfBoundsException {
        Printable toPrint = null;
        if (id_page <= nbpage) {
            toPrint = new Printable() {
                @Override
                public int print(Graphics g, PageFormat formatimp, int indexpage)
                        throws PrinterException {
                    //On décale en un point o`u on peut ecrire
                    Graphics2D graphics = (Graphics2D) g;
                    graphics.translate((int) x0, (int) y0);
                    AffineTransform originaltrans = graphics.getTransform();
                    int limit = barcode_par_page;
                    if (id_page == nbpage) {
                        limit = nb_derniere_page;
                    }
                    graphics.scale(downscale, downscale);
                    for (int i = 0; i < limit; i++) {
                        int id = i + (id_page) * barcode_par_page;
                        Barcode b = liste.get(id);
                        //graphics.drawString(String.valueOf(id), 0, 0);
                        graphics.drawRenderedImage(b.toBufferedImg(), null);
                        graphics.translate(0, (Barcode.getSizeY() + marge));
                    }
                    graphics.setTransform(originaltrans);
                    return Printable.PAGE_EXISTS;
                }
            };
        } else {
            toPrint = new Printable() {
                @Override
                public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
                        throws PrinterException {

                    return Printable.NO_SUCH_PAGE;
                }
            };
        }
        return toPrint;
    }
}
